<?php

declare(strict_types=1);

namespace app\api\controller\customer;

use app\api\controller\Api;
use app\common\config\logic\SourceLogic;
use app\common\customer\model\Customer;
use app\common\customer\model\CustomerAllocate;
use app\common\customer\model\CustomerBanquet;
use app\common\customer\model\CustomerContact;
use app\common\customer\model\CustomerFavorite;
use app\common\customer\model\CustomerSource;
use app\common\customer\model\CustomerVisit;
use app\common\system\logic\UserLogic;
use app\common\third\Excel;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\facade\Log;
use util\Format;

class Allocate extends Api
{
    // 我的跟进
    public function index() 
    {
        $post = $this->request->post();
        $user = $this->request->user;
        $isMobileRequest = $this->request->isMobile();

        $where = [];
        if ($user['user_type'] == 2) {
            $userLogic = new UserLogic();
            $staffIds = $userLogic->getDptUserIds($user['id']);
            $where[] = ['user_id', 'in', $staffIds];
        } else {
            $where[] = ['user_id', '=', $user['id']];
        }
        
        if (!empty($post['user_id'])) $where[] = ['user_id', 'in', $post['user_id']];
        if (isset($post['from_user_id']) && !empty($post['from_user_id'])) $where[] = ['from_user_id', 'in', $post['from_user_id']];
        if (isset($post['is_recommend']) && $post['is_recommend'] != '') $where[] = ['is_recommend', '=', $post['is_recommend']];
        if (isset($post['status']) && !empty($post['status'])) $where[] = ['status', 'in', $post['status']];
        if (isset($post['allocate_date_range']) && !empty($post['allocate_date_range'])) {
            $dateRange = Format::dateRange($post['allocate_date_range']);
            $where[] = ['create_time', 'between', $dateRange];
        }
        if (isset($post['next_visit_time']) && !empty($post['next_visit_time'])) {
            $dateRange = Format::dateRange($post['next_visit_time']);
            $where[] = ['next_visit_time', 'between', $dateRange];
        }
        if (!empty($post['next'])) {
            $today = strtotime('today');
            $where[] = ['next_visit_time', ">", 0];
            $orderBy = "next_visit_time asc,id asc";
        } else {
            $orderBy = "id desc";
        }

        $hasWhere = [];
        if (isset($post['category_id']) && !empty($post['category_id'])) $where[] = ['Customer.category_id', 'in', $post['category_id']];
        if (isset($post['creator_id']) && !empty($post['creator_id'])) $hasWhere[] = ['Customer.operator_id', 'in', $post['creator_id']];
        if (isset($post['source_id']) && !empty($post['source_id'])) {
            $sourceLogic = new SourceLogic();
            $children = $sourceLogic->getChildren($post['source_id']);
            if (count($children) > 1) {
                $hasWhere[] = ['Customer.source_id', 'in', $children];
            } else {
                $hasWhere[] = ['Customer.source_id', '=', $children[0]];
            }
        }
        if (isset($post['create_date_range']) && !empty($post['create_date_range'])) {
            $dateRange = Format::dateRange($post['create_date_range']);
            $hasWhere[] = ['Customer.create_time', 'between', $dateRange];
        }

        list($cfg) = Format::pagination();
        $model = CustomerAllocate::hasWhere('member', $hasWhere)->with('member')->where($where);

        // 无效原因 cause
        if (isset($post['cause']) && $post['cause'] != '') {
            $cause = $post['cause'];
            $model->whereIn('member_id', function ($query) use ($cause) {
                $query->table('tk_member_visit')->where('invalid', $cause)->field('member_id');
            });
        }

        // company_name
        if (isset($post['company_name']) && !empty($post['company_name'])) {
            $company_name = $post['company_name'];
            $model->whereIn('member_id', function ($query) use ($company_name) {
                $query->table('tk_member_banquet')->whereLike('company_name', "%{$company_name}%")->field('id');
            });
        }

        // table_amount
        if (isset($post['table_amount']) && !empty($post['table_amount'])) {
            $table_amount = $post['table_amount'];
            $model->whereIn('member_id', function ($query) use ($table_amount) {
                $query->table('tk_member_banquet')->whereLike('table_amount', "%{$table_amount}%")->field('member_id');
            });
        }

        // event_date
        if (isset($post['event_date']) && !empty($post['event_date'])) {
            $event_date = $post['event_date'];
            $model->whereIn('member_id', function ($query) use ($event_date) {
                $query->table('tk_member_banquet')->whereLike('event_date', "%{$event_date}%")->field('member_id');
            });
        }

        if (isset($post['keyword']) && !empty($post['keyword'])) {
            $contactType = $post['contact_type'] ?? 1;
            $keyword = $post['keyword'];
            $model->whereIn('member_id', function ($query) use ($keyword, $contactType) {
                if ($contactType == 1) {
                    if (strlen($keyword) == 11) {
                        $query->table('tk_member_contact')->where('contact_type', 1)->where('contact', $keyword)->field('member_id');
                    } else {
                        $query->table('tk_member_contact')->where('contact_type', 1)->whereLike('contact', "%{$keyword}")->field('member_id');
                    }
                } else {
                    $query->table('tk_member_contact')->where('contact', $keyword)->field('member_id');
                }
            });
        }

        if (empty($post['is_export'])) {
            $pg = $model->order($orderBy)->paginate($cfg);
            $rows = $pg->getCollection();
            foreach ($rows as $row) {
                if ($isMobileRequest) {
                    $row->append(['creator', 'from_user', 'user', 'visit_status']);
                } else {
                    $row->append(['creator', 'from_user', 'user', 'visit_status', 'last_visit', 'product']);
                }
                $row->member->append(['category', 'source', 'creator', 'contact']);
            }
            // 返回接口数据
            $result['list'] = $rows;
            $result['user'] = $user;
            $result['total'] = $pg->total();
            return success($result, '获取数据成功');
        } else {
            $rows = $model->order($orderBy)->select();
            $expData = [];
            foreach ($rows as $row) {
                $row->append(['user', 'visit_status']);
                $row->member->append(['category', 'source', 'creator', 'contacts', 'sources']);

                $data = [];
                $data['fullname'] = $row->member['fullname'];
                $data['contacts'] = implode(';', array_column($row->member['contacts'], 'contact'));
                $data['source'] = $row->member['source']['title'] ?? "";
                $data['sources'] = implode(';', array_column($row->member['sources'], 'title'));
                $data['category'] = $row->member['category']['title'];
                $data['creator'] = $row->member['creator']['realname'];
                $data['user'] = $row['user']['realname'];
                $data['visit_status'] = $row['visit_status']['title'];
                $data['create_time'] = $row['create_time'];
                $data['remark'] = $row->member['remark'];
                $data['recommend'] = $row['is_recommend'] == 1 ? '是' : '否';
                array_push($expData, $data);
            }

            // 姓名，电话，渠道，重复渠道，客资类型，创建人，跟进人，跟进状态，创建时间，备注，是否接受推荐
            $header = [
                'fullname' => '姓名',
                'contact' => '电话',
                'source' => '渠道',
                'channel' => '重复渠道',
                'category' => '客资类型',
                'creator' => '创建人',
                'user' => '跟进人',
                'visit_status' => '跟进状态',
                'create_time' => '创建时间',
                'remark' => '备注',
                'recommend' => '是否接受推荐',
            ];


            // 使用phpoffice导出excel
            return Excel::exportExcel($expData, $header, '客资分配');
        }
    }

    // dashboard 季总
    public function dashboard()
    {
        $model = new CustomerAllocate();
        $user = $this->request->user;
        $where = [];
        // 今日的客资
        $today = strtotime('today');
        $where[] = ['user_id', '=', $user['id']];
        $where[] = ['create_time', 'between', [$today, time()]];
        $result['total'] = $model->where($where)->count();

        // 分别获取 未跟进status=1、有效status=5、未接通status=3
        // 未跟进
        $where[] = ['status', '=', 1];
        $result['unfollow'] = $model->where($where)->count();

        // 有效
        $where[] = ['status', '=', 5];
        $result['valid'] = $model->where($where)->count();

        // 未接通
        $where[] = ['status', '=', 3];
        $result['unconnect'] = $model->where($where)->count();

        return success($result, "获取数据成功");
    }

    /**
     * 读取分配信息
     * @param int id 分配ID
     * @return \think\response\Json
     * @throws DbException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function read()
    {
        $post = $this->request->post();
        if (empty($post['id'])) return error([], "参数错误");
        $user = $this->request->user;

        $allocateModel = new CustomerAllocate();
        $allocate = $allocateModel->where('id', $post['id'])->find();
        if (empty($allocate)) return error([], "数据已不存在");
        $allocate->append(['user', 'from_user', 'visit_status', 'assign_type']);
        $result['allocate'] = $allocate;

        $memberId = $allocate->member_id;
        $customerModel = new Customer();
        $customer = $customerModel->where('id', $memberId)->find();
        if (empty($customer)) return error([], "客资已不存在");
        $customer->append(['creator', 'source', 'category', 'visit_status']);
        $result['customer'] = $customer;

        // 获取客资的联系方式
        $contactModel = new CustomerContact();
        $contacts = $contactModel->where('member_id', $memberId)->select();
        foreach ($contacts as $row) {
            $row->append(['role_type', 'tag']);
        }
        $result['contacts'] = $contacts;

        // 获取意向产品
        $productModel = new CustomerBanquet();
        $products = $productModel->where('member_id', $memberId)->select();
        foreach ($products as $row) {
            $row->append(['category', 'creator', 'city']);
        }
        $result['products'] = $products;

        // 获取拥有者
        $allocateModel = new CustomerAllocate();
        $owners = $allocateModel->field(['id', 'from_user_id', 'user_id', 'visit_times', 'create_time', 'next_visit_time'])->where('member_id', $memberId)->order('visit_times desc,id desc')->select();
        foreach ($owners as $row) {
            $row->append(['from_user', 'user']);
        }
        $result['owners'] = $owners;

        // 获取跟进记录
        $visitModel = new CustomerVisit();
        $visits = $visitModel->where('member_id', $memberId)->order('id desc')->select();
        foreach ($visits as $row) {
            $row->append(['user', 'status_title']);
        }
        $result['visits'] = $visits;

        // 获取收藏信息
        $where = [];
        $where['member_id'] = $memberId;
        $where['user_id'] = $user['id'];
        $favModel = new CustomerFavorite();
        $fields = 'member_id,user_id,type';
        $result['favorites'] = $favModel->where($where)->field($fields)->select();

        // 重复渠道
        $sourceModel = new CustomerSource();
        $sources = $sourceModel->where('member_id', $memberId)->select();
        foreach ($sources as $row) {
            $row->append(['source', 'creator']);
        }
        $result['sources'] = $sources;

        return success($result, "获取数据成功");
    }

    // 手动分配，assign_type=1
    public function handle()
    {
        $post = $this->request->post();
        // 都是数组
        if (empty($post['allocateIds']) || empty($post['ids'])) return error([], "参数错误");
        $ids = $post['ids'];

        // 验证用户权限
        $user = $this->request->user;

        // 获取要分配的客资列表
        $customerModel = new CustomerAllocate();
        $list = $customerModel->whereIn('id', $post['allocateIds'])->select();
        // 记录分配结果
        $success = $failed = [];
        $notices = [];

        $Message = new \app\common\third\Message();

        foreach ($ids as $userId) {
            foreach ($list as $row) {
                $row->append(['contact']);
                // 分配数据
                $data = [];
                $data['member_id'] = $row->member_id;
                $data['create_id'] = $row->create_id;
                $data['from_user_id'] = $user['id'];
                $data['operate_id'] = $user['id'];
                $data['user_id'] = $userId;
                $data['assign_type'] = 3;
                // 提醒数据
                $notice = [];
                $notice['from_user_id'] = $user['id'];
                $notice['user_id'] = $userId;
                $notice['type'] = 1;

                try {
                    $allocateModel = new CustomerAllocate();
                    $allocateModel->save($data);
                    array_push($success, $data);
                    $row->save(['assign_status' => 1]);

                    $contact = Format::mobile($row->contact['contact']);
                    // 提醒数据
                    $notice['content'] = $Message->buildCustomerMessage($user, $userId, ['id' => $allocateModel->id, 'contact' => $contact]);
                    $notice['options'] = ['allocate_id' => $allocateModel->id];
                    array_push($notices, $notice);
                } catch (DbException $e) {
                    \think\facade\Log::write($e->getMessage());
                    array_push($failed, $data);
                }
            }
        }

        $result['success'] = count($success);
        $result['failed'] = count($failed);

        // 发送提醒
        if (!empty($notices)) {
            $noticeModel = new \app\common\system\model\Notice();
            $noticeModel->saveAll($notices);
        }

        // 核销表单token
        // $formLogic = new FormLogic();
        // $formLogic->removeToken($post['form_token']);
        return success($result, "分配成功" . count($success) . "个，失败" . count($failed) . "个");
    }

    // 全号获取
    public function acquisition()
    {
        $post = $this->request->post();
        if (empty($post['mobile'])) return error([], "参数错误");
        $user = $this->request->user;

        $contactModel = new CustomerContact();
        try {
            $contact = $contactModel->where('contact', $post['mobile'])->find();
        } catch (DataNotFoundException $e) {
            return error([], "客资不存在");
        } catch (DbException $e) {
            return error([], $e->getMessage());
        }

        $where = [];
        $where[] = ['member_id', '=', $contact['member_id']];
        $where[] = ['user_id', '=', $user['id']];
        $allocateModel = new CustomerAllocate();

        $allocate = $allocateModel->where($where)->find();
        if (!empty($allocate)) {
            return error([], "请勿重复获取");
        }

        $data = [];
        $data['member_id'] = $contact['member_id'];
        $data['create_id'] = $user['id'];
        $data['from_user_id'] = $user['id'];
        $data['operate_id'] = $user['id'];
        $data['user_id'] = $user['id'];
        $data['assign_type'] = 4;
        try {

            $allocateModel->save($data);
        } catch (DbException $e) {
            return error([], $e->getMessage());
        }

        return success([], "获取成功");
    }

    public function recommend()
    {
        $post = $this->request->post();
        if (empty($post['id'])) return error([], "参数错误");

        $user = $this->request->user;
        $model = new CustomerAllocate();
        $allocate = $model->where('id', $post['id'])->find();
        if ($allocate['user_id'] != $user['id']) {
            return error([], "无权操作");
        }

        if ($allocate['is_recommend'] == $post['is_recommend']) return error([], "请勿重复操作");

        $data = [];
        $data['is_recommend'] = $post['is_recommend'];
        try {
            $allocate->save($data);
        } catch (DbException $e) {
            return error([], $e->getMessage());
        }

        return success([], "操作成功");
    }

    public function level()
    {
        $post = $this->request->post();
        if (empty($post['id'])) return error([], "参数错误");

        $user = $this->request->user;
        $model = new CustomerAllocate();
        $allocate = $model->where('id', $post['id'])->find();
        if ($allocate['user_id'] != $user['id']) {
            return error([], "无权操作");
        }

        if ($allocate['level'] == $post['level']) return error([], "请勿重复操作");

        $data = [];
        $data['level'] = $post['level'];
        try {
            $allocate->save($data);
        } catch (DbException $e) {
            return error([], $e->getMessage());
        }

        return success([], "操作成功");
    }

    public function batchUpdateStatus()
    {
        $post = $this->request->post();
        $user = $this->request->user;
        if (empty($post['ids'])) return error([], "请选择客资");
        if (empty($post['status'])) return error([], "请选择要更新的状态");

        $where = [];
        $where[] = ['id', 'in', $post['ids']];
        if ($user['user_type'] == 2) {
            $userLogic = new UserLogic();
            $staffIds = $userLogic->getDptUserIds($user['id']);
            $where[] = ['user_id', 'in', $staffIds];
        } else {
            $where[] = ['user_id', '=', $user['id']];
        }
        $model = new CustomerAllocate();
        $count = $model->where($where)->count();
        if ($count != count($post['ids'])) {
            return error([], "权限异常");
        }

        try {
            $where = [];
            $where[] = ['id', 'in', $post['ids']];
            CustomerAllocate::update(['status' => $post['status']], $where);
        } catch (DbException $e) {
            return error([], $e->getMessage());
        }

        return success([], "操作成功");
    }

    // 获取客资详情 (季总)
    public function details()
    {
        $id = $this->request->param('id');
        if (empty($id)) return error([], "参数错误");

        // 获取分配信息
        $user = $this->request->user;
        $model = new CustomerAllocate();
        $allocate = $model->where('id', $id)->find();
        if (empty($allocate)) return error([], "客资不存在");
        if ($allocate['user_id'] != $user['id']) {
            return error([], "无权操作");
        }
        $allocate->append(['user', 'from_user', 'visit_status', 'assign_type']);
        $result['allocate'] = $allocate;

        // 获取客资详情
        $memberId = $allocate->member_id;
        $customerModel = new Customer();
        $customer = $customerModel->where('id', $memberId)->find();
        if (empty($customer)) return error([], "客资已不存在");
        $customer->append(['creator', 'source', 'category', 'visit_status']);
        $result['customer'] = $customer;

        // 获取客资的联系方式
        $contactModel = new CustomerContact();
        $contacts = $contactModel->where('member_id', $memberId)->select();
        foreach ($contacts as $row) {
            $row->append(['role_type', 'tag']);
        }
        $result['contacts'] = $contacts;

        // 获取意向产品
        $productModel = new CustomerBanquet();
        $product = $productModel->where('member_id', $memberId)->find();
        if (!empty($product)) {
            $product->append(['category', 'creator', 'city']);
        }
        $result['banquet'] = $product;

        // 当前跟进人的跟进记录
        $visitModel = new CustomerVisit();
        $visits = $visitModel->where('member_id', $memberId)->where('user_id', $user['id'])->order('id desc')->select();
        foreach ($visits as $row) {
            $row->append(['user', 'status_title']);
        }
        $result['visits'] = $visits;

        // 返回数据
        return success($result, "获取数据成功");
    }

    public function share()
    {
        $post = $this->request->post();
        if (empty($post['user_id'])) {
            return error([], "请选择要分享的用户");
        }

        $allocateId = $this->request->param('allocate_id');
        $memberId = $this->request->param('member_id');
        $user = $this->request->user;
        $model = new CustomerAllocate();
        $allocate = $model->where('id', $allocateId)->where('user_id', $user['id'])->find();
        if (empty($allocate)) return error([], "无权限");
        if ($allocate['member_id'] != $memberId) return error([], "客资不匹配");

        $model = new CustomerAllocate();
        $model->startTrans();
        try {
            $data = [];
            $data['member_id'] = $memberId;
            $data['create_id'] = $allocate->create_id;
            $data['from_user_id'] = $user['id'];
            $data['user_id'] = $post['user_id'];
            $data['assign_type'] = 2;
            $model->save($data);
            $model->commit();
        } catch (DbException $e) {
            $model->rollback();
            return error([], $e->getMessage());
        }

        return success([], "分享成功");
    }
}
